package com.bridgeintelligent.tag.engine.mvc.service.impl;

import com.bridgeintelligent.tag.engine.api.IndexNameInfo;
import com.bridgeintelligent.tag.engine.api.theme.ThemeDetailResult;
import com.bridgeintelligent.tag.engine.api.theme.ThemeQueryModel;
import com.bridgeintelligent.tag.engine.core.cache.CacheConfig;
import com.bridgeintelligent.tag.engine.core.cache.CacheUtils;
import com.bridgeintelligent.tag.engine.es.base.ESQueryUtils;
import com.bridgeintelligent.tag.engine.es.model.DataSetModel;
import com.bridgeintelligent.tag.engine.es.query.EsQueryBuilder;
import com.bridgeintelligent.tag.engine.mvc.service.IEsDateService;
import com.bridgeintelligent.tag.engine.mvc.service.IThemeDetailService;
import com.bridgeintelligent.tag.engine.parse.DataSetParse;
import com.bridgeintelligent.tag.utils.FieldHandler;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.Strings;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@AllArgsConstructor
@Service
@Slf4j
public class ThemeDetailService implements IThemeDetailService {


    public static String GROUP_FORMAT = "%s_%s";

    private final IEsDateService dateService;

    @Override
    public ThemeDetailResult themeDetailQuery(ThemeQueryModel queryModel)  {

        //封装查询数据
        DataSetModel dataSetModel = new DataSetModel();
        dataSetModel.setFrom(queryModel.getFrom());
        dataSetModel.setSize(queryModel.getSize());
        //list转set,过滤重复字段
        Map<String, String> relation = dateService.symbolRelation(queryModel.getIndexId());
        List<String> fieldsSet = fetchRealField(queryModel.getFields(), queryModel.getDataDate(),relation);
        //设置包含项
        dataSetModel.setIncludes(fieldsSet.toArray(new String[fieldsSet.size()]));
        //设置排除项，排除项为空
        dataSetModel.setExcludes(Strings.EMPTY_ARRAY);
        //将FilterGroup转换为QueryBuilder,然后给dataSetModel设值
        if (FieldHandler.FALSE.equals(queryModel.getTimeType())){
            dataSetModel.setQueryBuilder(EsQueryBuilder.buildFilter(queryModel.getFilterGroup()));
        }else{
            dataSetModel.setQueryBuilder(QueryBuilders.termsQuery(FieldHandler.CUSTOMER_FLAG,queryModel.getCustomerId()));
        }
        IndexNameInfo indexNameInfo = CacheUtils.getCacheInfo(CacheConfig.CONFIGURATION_INFO, queryModel.getIndexId());
        return DataSetParse.themeDetailQuery(ESQueryUtils.dataSetSearch(indexNameInfo.getDataDate(), dataSetModel), queryModel.getSize(), fieldsSet, queryModel.getDataDate());

    }

    @Override
    public int getTotalCount(ThemeQueryModel queryModel) throws IOException {
        IndexNameInfo indexNameInfo = CacheUtils.getCacheInfo(CacheConfig.CONFIGURATION_INFO, queryModel.getIndexId());
        SearchRequest searchRequest = new SearchRequest(indexNameInfo.getDataDate());
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        QueryBuilder queryBuilder;
        if (FieldHandler.FALSE.equals(queryModel.getTimeType())){
            queryBuilder = EsQueryBuilder.buildFilter(queryModel.getFilterGroup());
        }else{
            queryBuilder = QueryBuilders.termsQuery(FieldHandler.CUSTOMER_FLAG,queryModel.getCustomerId());
        }
        sourceBuilder.query(queryBuilder).trackTotalHits(true).size(0);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = ESQueryUtils.getClient().search(searchRequest, RequestOptions.DEFAULT);
        if (searchResponse != null){
            SearchHits hits = searchResponse.getHits();
            if (hits != null){
                TotalHits totalHits = hits.getTotalHits();
                if (totalHits != null){
                    return Integer.parseInt(String.valueOf(totalHits.value));
                }
            }
        }
        return 0;
    }

    private List<String> fetchRealField(List<String> fields, String dataDate,Map<String, String> relation) {

        return fields.stream()
                        .map(s -> {
                            return FieldHandler.addSuffixField(s,dataDate,relation);
                        })
                        .collect(Collectors.toList());
    }

}
